package org.litu.app.service.baseimpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.litu.app.constant.SysContant;
import org.litu.app.entity.system.*;
import org.litu.app.entity.vo.CommonData;
import org.litu.app.entity.vo.LoginUserInfo;
import org.litu.app.entity.vo.LoginUserMsg;
import org.litu.app.service.*;
import org.litu.core.base.SelectVo;
import org.litu.core.enums.ResultEnum;
import org.litu.core.exception.LtServerException;
import org.litu.core.login.PasswordUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 登录的服务层，逻辑处理
 *
 * @author yueye
 */
@Service
public class LoginServiceImpl implements ILoginExService {

    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ISysUserLoginService sysUserLoginService;
    @Autowired
    private ISysRoleService sysRoleService;
    @Autowired
    private ISysOrganizeService organizeService;
    @Autowired
    private ISysMenuService sysMenuService;
    @Autowired
    private ISysSystemService sysSystemService;
    @Autowired
    private ISysDictService sysDictService;

    /**
     * 系统编号认证，用于判断当前系统编码是否被管理
     *
     * @param systemCode
     * @return
     */
    @Override
    public boolean checkSystemCode(String systemCode) {
        LambdaQueryWrapper<SysSystem> query = Wrappers.lambdaQuery();
        query.eq(SysSystem::getCode, systemCode);
        SysSystem client = sysSystemService.getOne(query);

        return client != null;
    }

    /**
     * 根据用户的账号、密码信息，对账号信息进行校验，包括账号的用户名、密码等信息。
     *
     * @param systemCode 当前用户登录系统的编号
     * @param account    用户账号信息
     * @param password   账号密码信息
     * @return 如果登录成功返回用户信息，如果登录失败返回null， 或者抛出对应错误信息的异常
     * @author yueye
     */
    @Override
    public LoginUserInfo checkLogin(String systemCode, String account, String password) {
        // 获取用户以及验证账号
        SysUser user = sysUserService.getByAccount(account);
        // 未找到用户
        if (user == null) {
            throw new LtServerException(ResultEnum.UserPwdError);
        }
        // 用户被禁用
        if (user.getDeleteFlag().intValue() == SysContant.FLAG_TRUE) {
            throw new LtServerException(ResultEnum.UserNotEnable);
        }
        // 验证密码
        String userId = user.getId();
        SysUserLogin sysUserLogin = sysUserLoginService.getByUserId(userId);

        // 是否允许登录
        if (sysUserLogin.getEnableLogin().intValue() == SysContant.FLAG_FALSE) {
            throw new LtServerException(ResultEnum.UserNotEnable);
        }
        // 验证密码是否正确
        String nowPwd = PasswordUtil.getDbPassword(sysUserLogin.getSecretKey(), password);
        if (!nowPwd.equals(sysUserLogin.getPassword())) {
            throw new LtServerException(ResultEnum.UserPwdError);
        }

        return toUserInfo(user);
    }

    /**
     * 根据系统用户的信息，获取当前用户登录需要反馈的信息。
     *
     * @param userId     用户ID
     * @param systemCode 系统的Code
     * @return
     * @author yueye
     */
    @Override
    public LoginUserMsg getLoginMsg(String userId, String systemCode) {
        SysUser user = sysUserService.detail(userId);
        LoginUserInfo userInfo = toUserInfo(user);
        return getLoginMsg(userInfo, systemCode);
    }

    /**
     * 根据系统用户的信息，获取当前用户登录需要反馈的信息。
     *
     * @param user 用户信息
     * @return
     * @author yueye
     */
    @Override
    public LoginUserMsg getLoginMsg(LoginUserInfo user, String systemCode) {
        LoginUserMsg userMsg = new LoginUserMsg();
        userMsg.setUser(user);

        // 返回用户的所有权限信息
        List<String> powers = sysMenuService.userPowers(user.getId(), systemCode);
        // 是否有权限,如果没有权限则不允许登录
        if (powers == null || powers.size() == 0) {
            throw new LtServerException(ResultEnum.UserHasNoAuth);
        }
        userMsg.setPowers(powers);

        return userMsg;
    }

    /**
     * 更新用户登录表中的登录状态信息
     *
     * @param userId
     * @param loginStatus
     * @return
     * @author yueye
     */
    @Override
    public boolean changeLoginStatus(String userId, Integer loginStatus) {
        SysUserLogin sysUserLogin = sysUserLoginService.getByUserId(userId);
        sysUserLogin.setLoginStatus(loginStatus);
        if (loginStatus.equals(SysContant.FLAG_TRUE)) {
            sysUserLogin.setLastVisitTime(new Date());
            sysUserLogin.setLogonCount(sysUserLogin.getLogonCount() + 1);
        }

        sysUserLoginService.updateById(sysUserLogin);
        return false;
    }

    /**
     * 根据用户账号，获取用户的基本信息
     *
     * @param account
     * @return
     */
    @Override
    public LoginUserInfo getUserByAccount(String account) {
        SysUser user = sysUserService.getByAccount(account);
        return toUserInfo(user);
    }

    /**
     * 获取系统的数据
     *
     * @param systemCode
     * @param userId
     * @return
     */
    @Override
    public CommonData getCommonData(String systemCode, String userId) {
        CommonData data = new CommonData();
        if (SysContant.CURRENT_SYSTEM_CODE.equals(systemCode)) {
            // 系统当前所有的菜单信息
            List<String> menuTypes = new ArrayList<String>();
            menuTypes.add(SysContant.MENUTYPE_MODULE);
            menuTypes.add(SysContant.MENUTYPE_FUNCTION);
            List<SysMenu> menus = sysMenuService.userMenus(userId, systemCode, menuTypes);
            data.setMenus(menus);
        }

        // 字典信息获取
        LambdaQueryWrapper<SysDict> dictWrapper = Wrappers.lambdaQuery();
        dictWrapper.orderByAsc(SysDict::getSortNum);
        List<SysDict> dicts = sysDictService.list(dictWrapper);
        // 转化为需要返回的实体类
        Map<String, List<SelectVo>> dictArrCache = new HashMap<>(16);
        Map<String, Map<String, String>> dictCache = new LinkedHashMap<>();
        for (SysDict dict : dicts) {
            String dictCode = dict.getDictCode();
            if (!dictArrCache.containsKey(dictCode)) {
                dictArrCache.put(dictCode, new ArrayList<>());
            }
            if (!dictCache.containsKey(dictCode)) {
                dictCache.put(dictCode, new LinkedHashMap<>());
            }

            dictArrCache.get(dictCode).add(new SelectVo(dict.getCode(), dict.getName()));
            dictCache.get(dictCode).put(dict.getCode(), dict.getName());
        }
        data.setDictItemArr(dictArrCache);
        data.setDictItems(dictCache);

        return data;
    }

    /*=================== 以下为私有方法 ====================*/

    /**
     * 将系统用户转化为管理用户信息
     *
     * @param user
     * @return
     */
    private LoginUserInfo toUserInfo(SysUser user) {
        LoginUserInfo userInfo = new LoginUserInfo();
        userInfo.setId(user.getId());
        userInfo.setAccount(user.getAccount());
        userInfo.setName(user.getName());
        userInfo.setPhoto(user.getPhoto());
        userInfo.setWechat(user.getWechat());
        userInfo.setPhone(user.getPhone());
        userInfo.setEmail(user.getEmail());
        // TODO 改善下
        userInfo.setOrgCode(user.getDeptId());

        // 获取用户的角色信息
        List<String> roles = sysRoleService.userRoles(user.getId());
        userInfo.setRoles(roles);

        return userInfo;
    }

}
